package com.mcglib.flac
{
	import com.mcglib.ds.DicMap;
	
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	
	[Event(name="valueChange",type="com.mcglib.flac.FlacEvent")]
	[Event(name="itemClick",type="com.mcglib.flac.FlacEvent")]
	[Event(name="itemOver",type="com.mcglib.flac.FlacEvent")]
	[Event(name="itemOut",type="com.mcglib.flac.FlacEvent")]
	/**
	 *  
	 * @author ccw
	 * 
	 */
	public class FixedList extends FlacComponent
	{
		public function FixedList()
		{
			super();
		}
		
		private var _dataProvide:Array = [];
		
		private var _renderInstances:Array;
		
		private var _rendererClass:Class;
		
		private var _selectIndex:int = -1;
		
		private var _selectItem:*;
		
		private var _selectable:Boolean =  true;
		
		private var _selectProxyRender:IDataRenderer;
		
		public function get selectable():Boolean
		{
			return _selectable;
		}

		public function set selectable(value:Boolean):void
		{
			_selectable = value;
		}

		public function get selectItem():*
		{
			return _selectItem;
		}
		
		public function set selectItem(item:*):void{
			if(_selectItem==item)
				return;
			if(_selectProxyRender){
				_selectProxyRender.selected = false;
				_selectProxyRender = null;
			}
			for each(var render:IDataRenderer in proxyRenderDic.values()){
				if(render.data == item){
					
					_selectProxyRender = render;
					_selectProxyRender.selected = true;
					break;
				}
			}	
			
			_selectItem = item;
			dispatchSelectEvent();
			
		}
		
		public function get selectIndex():int
		{
			return _selectProxyRender?_selectProxyRender.itemIndex:-1;
		}
		
		public function set selectIndex(value:int):void
		{
			if(_selectIndex==value)
				return;
			if(value>=_renderInstances.length)
				throw new Error("selectIndex的取值范围应该在0到dataProvide的length-1之间,当前值为"+value);
			
			_selectIndex = value;
			
			if(_selectProxyRender){
				_selectProxyRender.selected = false;
			}
			
			if(_selectable){
				var renderInstance:DisplayObject = _renderInstances?(_renderInstances[value] as DisplayObject):null;
				
				if(renderInstance){
					
					var proxy:IDataRenderer = this.proxyRenderDic.getValue(renderInstance);
					if(proxy){
						
						_selectItem = proxy.data;
						_selectProxyRender = proxy;
						_selectProxyRender.selected = true;
						dispatchSelectEvent();
					}
				}
			}
		}
		
		public function get rendererClass():Class
		{
			return _rendererClass;
		}
		
		public function set rendererClass(value:Class):void
		{
			if(_rendererClass==value)
				return;
			
			_rendererClass = value;
			clearAndUpdate();
		}
		
		public function get renderInstances():Array
		{
			return _renderInstances;
		}
		
		public function set renderInstances(value:Array):void
		{
			if(_renderInstances==value)
				return;
			
			clearRenderInstanceEvent();
			
			_renderInstances = value;
			
			configRenderInstanceEvent();
			
			clearAndUpdate();
		}
		
		public function get dataProvide():Array
		{
			return _dataProvide;
		}
		
		public function set dataProvide(value:Array):void
		{
			
			/*if(_dataProvide==value){
				return;
			}*/
			
			clearSelect();
			
			_dataProvide = value;
			
			
			/*if(_dataProvide){
				update();
			}else{
				for each(var proxyRedner:IDataRenderer in proxyRenderDic.values()){
					proxyRedner.clearRenderer();
				}
			}*/
		}
		
		public function clearList():void{
			_rendererClass = null;
			_renderInstances = null;
			
			
			_dataProvide = null;
			for each(var proxyRedner:IDataRenderer in proxyRenderDic.values()){
				proxyRedner.clearRenderer();
			}
			
			proxyRenderDic.clear();
		}
		
		override public function present(refresh:Boolean=true):void{
			update();
		}
		
		private function update():void{
			
			
			
			if(_dataProvide && _renderInstances && _rendererClass){
				var isAC:Boolean = !(_dataProvide is Array);
				if(_dataProvide.length>_renderInstances.length)
					throw new Error("dataProvide的长度不能大于renderInstances的长度");
				
				if(_selectItem && isAC?!_dataProvide.contains(_selectItem):_dataProvide.indexOf(_selectItem)!=-1){
					
					if(_selectProxyRender){
						_selectProxyRender.clearRenderer();
					}
					
					if(_dataProvide.length>0){
						_selectItem = isAC?_dataProvide.getItemAt(0):_dataProvide[0];
					}else{
						_selectItem = null;
					}
					
					dispatchSelectEvent();
					
				}else if(_selectProxyRender)
					_selectProxyRender.selected = false;
				
				
				
				for(var i:int=0;i<_dataProvide.length;i++){
					var data:* = isAC?_dataProvide.getItemAt(i):_dataProvide[i];
					var renderInstance:DisplayObject = _renderInstances[i] as DisplayObject;
					var proxyRender:IDataRenderer = getProxyRender(renderInstance);
					proxyRender.itemIndex = i;
					proxyRender.data = data;
					
					if(data==_selectItem)
					{
						proxyRender.selected = true;
						_selectProxyRender = proxyRender;
					}	
				}
				
				
				
				var l:int = _dataProvide.length;
				while(l<_renderInstances.length){
					var restRenderInstance:DisplayObject = _renderInstances[l] as DisplayObject;
					var restProxyRender:IDataRenderer = getProxyRender(restRenderInstance);
					restProxyRender.itemIndex = l;
					restProxyRender.clearRenderer();
					l++;
				}
				
				
			}
		}
		
		private var proxyRenderDic:DicMap = new DicMap;
		private function getProxyRender(renderInstance:DisplayObject):IDataRenderer{
			var proxyRender:IDataRenderer = proxyRenderDic.getValue(renderInstance) as IDataRenderer;
			if(proxyRender==null){
				proxyRender = (new _rendererClass) as IDataRenderer;
				proxyRender.initDataRenderer(renderInstance,this);
				proxyRenderDic.put(renderInstance,proxyRender);
			}
			
			return proxyRender;
		}
		
		private function clearProxyRenderDic():void{
			proxyRenderDic.clear();
		}
		
		private function clearAndUpdate():void{
			clearProxyRenderDic();
			//update();
		}
		
		private function configRenderInstanceEvent():void{
			for each(var render:DisplayObject in _renderInstances){
				render.addEventListener(MouseEvent.CLICK,onRenderInstanceClick);
				render.addEventListener(MouseEvent.MOUSE_OVER,onRenderInstanceMouseOver);
				render.addEventListener(MouseEvent.MOUSE_OUT,onRenderInstanceMouseOut);
			}	
		}
		
		private function clearRenderInstanceEvent():void{
			for each(var render:DisplayObject in _renderInstances){
				render.removeEventListener(MouseEvent.CLICK,onRenderInstanceClick);
				render.removeEventListener(MouseEvent.MOUSE_OVER,onRenderInstanceMouseOver);
				render.removeEventListener(MouseEvent.MOUSE_OUT,onRenderInstanceMouseOut);
			}
		}
		
		
		private function onRenderInstanceClick(e:MouseEvent):void{
			if(_selectable){
				var uiInstance:DisplayObject = e.currentTarget as DisplayObject;
				var proxyRender:IDataRenderer = proxyRenderDic.getValue(uiInstance) as IDataRenderer;
				if(proxyRender && proxyRender.selectable){
					if(_selectItem!=proxyRender.data){
						if(_selectProxyRender){
							_selectProxyRender.selected = false;
						}	
						
						_selectProxyRender = proxyRender;
						_selectProxyRender.selected = true;
						_selectItem = proxyRender.data;
						
						dispatchSelectEvent();
					}
					proxyRender.onMouseClick(e);
					var clickEvt:FlacEvent = new FlacEvent(FlacEvent.ITEM_CLICK);
					clickEvt.value = proxyRender.data;
					clickEvt.index = proxyRender.itemIndex;
					clickEvt.render = proxyRender;
					dispatchEvent(clickEvt);
				}
			}		
		}
		
		private function onRenderInstanceMouseOver(e:MouseEvent):void{
			if(_selectable){
				var uiInstance:DisplayObject = e.currentTarget as DisplayObject;
				var proxyRender:IDataRenderer = proxyRenderDic.getValue(uiInstance) as IDataRenderer;
				if(proxyRender && proxyRender.selectable){
					proxyRender.onMouseOver(e);
					
					
					var evt:FlacEvent = new FlacEvent(FlacEvent.ITEM_OVER);
					evt.value = proxyRender.data;
					evt.index = proxyRender.itemIndex;
					evt.render = proxyRender;
					dispatchEvent(evt);
				}
			}
		}
		
		private function onRenderInstanceMouseOut(e:MouseEvent):void{
			if(_selectable){
				var uiInstance:DisplayObject = e.currentTarget as DisplayObject;
				var proxyRender:IDataRenderer = proxyRenderDic.getValue(uiInstance) as IDataRenderer;
				if(proxyRender && proxyRender.selectable){
					proxyRender.onMouseOut(e);	
					
					var evt:FlacEvent = new FlacEvent(FlacEvent.ITEM_OUT);
					evt.value = proxyRender.data;
					evt.index = proxyRender.itemIndex;
					evt.render = proxyRender;
					dispatchEvent(evt);
				}
			}
		}
		
		private function clearSelect():void{
			if(_selectProxyRender)
				_selectProxyRender.selected = false;
			
			_selectProxyRender = null;
			_selectIndex = -1;
			_selectItem = null;
		}
		
		private function dispatchSelectEvent():void{
			var e:FlacEvent = new FlacEvent(FlacEvent.VALUE_CHANGE);
			e.value = _selectItem;
			if(_selectItem && _selectProxyRender)
				e.index = _selectProxyRender.itemIndex;
			else
				e.index = -1;	
			dispatchEvent(e);
		}
	
	}
}